//-------------------------------------------------------
// Copyright (c) 
// All rights reserved.
//
// File Name: CMapT.h
// File Des: 统一的Map模板，线程安全
// File Summary: 子类在析构时调用RemoveAll!
// Cur Version: 1.0
// Author:
// Create Data:2021-6-23
// History:
//      <Author>     <Time>        <Version>      <Des>
//      zeron        2021-6-23     1.0
//-------------------------------------------------------
#pragma once
#include <map>
#include "MutexLock.h"

/// <summary>
///        统一的Map模板
/// </summary>
/// <remarks>
///        由子类在析构时调用RemoveAll!
/// </remarks>
template <class TKey, class TObj> class CMapT {
public:
  CMapT() {}
  /*RemoveAll函数中必须由重载函数的子类调用，不然重载函数无效*/
  virtual ~CMapT() {
  }

  /// -------------------------------------------------
  /// @brief    key是否已存在
  /// @param[in]         key    用于查找Map的key
  /// @return true:存在，false:不存在
  bool IsKeyExist(const TKey &key) const {
    /// 超出作用域需要外部保护
      Misc::Mutex::Lock lock(m_mutex);
      return m_Map.end() != m_Map.find(key);
  }

  /// -------------------------------------------------
  /// @brief 通过key获取obj
  /// @param[in]         key    用于查找Map的key
  /// @param[out]         obj    用于返回Map的obj
  /// @remark 安全获取方式
  /// @return true:获取成功,false:获取失败
  bool GetObjByKey(const TKey &key, TObj &obj) {
    bool bRet = false;
    do {
        Misc::Mutex::Lock lock(m_mutex);
        if (!IsKeyExist(key)) {
            break;
        }
        obj = m_Map[key];
        bRet = true;
    } while (false);
    return bRet;
  }

  /// -------------------------------------------------
  /// @brief 通过key获取obj
  /// @param[in]         key    用于查找Map的key
  /// @remark 不安全方式
  /// @return 返回对象
  TObj &GetObjByKey(const TKey &key) {
      Misc::Mutex::Lock lock(m_mutex);
      return m_Map[key];
  }

  /// -------------------------------------------------
  /// @brief 设置Key
  /// @param[in]         key    用于传入Map的key
  /// @param[in]         obj    用于传入Map的obj
  /// @return true:成功,false:key已存在
  bool AddKey(const TKey &key, const TObj &obj) {
    bool bRet = false;
    do {
        Misc::Mutex::Lock lock(m_mutex);
        if (true == IsKeyExist(key)) {
            break;
        }
        m_Map[key] = obj;
        bRet = true;
    } while (false);
    return bRet;
  }

  /// -------------------------------------------------
  /// @brief 强制设置Key
  /// @param[in]         key    用于传入Map的key
  /// @param[in]         obj    用于传入Map的obj
  /// @remark key已存在则覆盖key
  /// @return 无
  void SetKey(const TKey &key, const TObj &obj) {
      Misc::Mutex::Lock lock(m_mutex);
      m_Map[key] = obj;
  }

  /// -------------------------------------------------
  /// @brief 删除key
  /// @param[in]         key    用于传入Map的key
  /// @return true:移除成功,false:移除失败
  bool RemoveKey(const TKey &key) {
    bool bRet = false;
    do {
        Misc::Mutex::Lock lock(m_mutex);
        if (!IsKeyExist(key)) {
          break;
        }
        // 调用删除前预处理函数
        PreMapKeyRemove(m_Map[key]);
        m_Map.erase(key);
        bRet = true;
    } while (false);
    return bRet;
  }

    /// -------------------------------------------------
    /// @brief 删除所有key
    /// @return 无
    void RemoveAll() {
        Misc::Mutex::Lock lock(m_mutex);
        typename std::map< TKey, TObj>::iterator it;
        while ((it = m_Map.begin()) != m_Map.end()) {
            // 释放内存
            PreMapKeyRemove(it->second);
            m_Map.erase(it);
        }
        m_Map.clear();
    }

  /// -------------------------------------------------
  /// @brief 获取数目
  /// @return 数目
  int GetCount() const {
      Misc::Mutex::Lock lock(m_mutex);
      return (int)m_Map.size();
  }

  /// -------------------------------------------------
  /// @brief 可重载，外部重载
  /// @remark 外部来重载预处理删除项
  /// @return 无
    virtual void PreMapKeyRemove(const TObj &obj) {
        // 外部来重载预处理删除项
    }

protected:
    std::map< TKey, TObj>     m_Map;
    Misc::Mutex              m_mutex;
};
